﻿using System;
using System.Collections.Generic;
using ApplicationLibrary;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.SqlConnector;
using ProjectManager.Masters.ModuleData;

namespace ProjectManager.Masters.Forms
{
    public partial class StepImprov : ApplicationLibrary.DBManager.DocumentForm, iDocument
    {
        private BindableOject<int> bdoProjectType = new BindableOject<int>();
        private EnumsManager<Status> StatusManager = new EnumsManager<Status>(Properties.Resources.ResourceManager);
        private PartialCounter CounterManager = new PartialCounter(Properties.Resources.ResourceManager);
        private RRProjects rrProjects = null;

        //@@ todo
        // SqLite e SqlServer differs
        private ComboBoxManager ProjectManager = new ComboBoxManager();
        private DRProject drProject = null;
        private Counters projectType = 0;

        #region Interface
        public ApplicationLibrary.ExtendedControls.ExTabControl masterTabControl { get { return exTabControl1; } }
        public Counters ProjectType { get { return projectType; } }
        public int ProjectNumb { get { return cntNumber.CounterNumericValue; } }
        public string Description { get { return txtDescription.Text; } }
        #endregion

        public StepImprov(string name, Counters type)
            : base(name)
        {
            InitializeComponent();
            projectType = type;

            switch (projectType)
            {
                case Counters.Improvement:
                    this.Text = Properties.Resources.C_Improvements;
                    break;

                case Counters.Step:
                    this.Text = Properties.Resources.C_Steps;
                    break;
            }
        }

        protected override void OnAttachData()
        {
            dbManager = new dbmanagerStepImprov("StepImprov", new RadarProjects(projectType), this);
            dbManager.AddMaster(this, PM_Project.Name, true);
            dbManager.AddSlave("SLAVESTATUS", false);

            cntNumber.AttachCounterType(projectType.Int(), GlobalInfo.CurrentDate, null);
            cbbProduct.AttachDataReader<string>(new RRDescriptions(DescriptionType.E_Products), PM_Descriptions.Code, PM_Descriptions.Description);
            cbbVersion.AttachDataReader<string>(new RRDescriptions(DescriptionType.E_Versions), PM_Descriptions.Code, PM_Descriptions.Description);

            if (GlobalInfo.LoginInfo.ProviderType == ProviderType.SQLite)
                ProjectManager.AttachDataReader<long>(new RRProjects(Counters.Project), PM_Project.Code, PM_Project.Description, false);
            else
                ProjectManager.AttachDataReader<int>(new RRProjects(Counters.Project), PM_Project.Code, PM_Project.Description, false);

            CounterManager.AttachTo(cbbFatherType);
            ProjectManager.AttachTo(cbbFather);
            StatusManager.AttachTo(cbbStatus);

            drProject = new DRProject(Counters.Project, false);

            dgwBugs.AddReadOnlyColumn(PM_Project.Type, true);
            dgwBugs.AddReadOnlyColumn(PM_Project.Description, true);
            dgwBugs.AddReadOnlyColumn(PM_Project.Code, true);
            dgwBugs.AddReadOnlyColumn(PM_Project.Status, true);
            colBugsStatus.EnumsType = typeof(Status);
            colBugsStatus.ResourceManager = Properties.Resources.ResourceManager;

            dgwBugs.AutoGenerateColumns = false;
            dgwBugs.DataSource = dbManager.Dataset.Tables["SLAVESTATUS"];

            base.OnAttachData();
        }

        protected override void OnBindData()
        {
            BindControl(cntNumber, PM_Project.Code, NullValue.NotSet, Findable.YES);
            BindControl(ctbDate, PM_Project.Date);
            BindControl(txtDescription, PM_Project.Description);
            BindControl(cbbProduct, PM_Project.Product, "SelectedValue", NullValue.NotSet);
            BindControl(cbbVersion, PM_Project.Version, "SelectedValue", NullValue.NotSet);
            BindControl(cbbStatus, PM_Project.Status, "SelectedValue", NullValue.NotSet);
            BindControl(cbbFatherType, PM_Project.FatherType, "SelectedValue", NullValue.NotSet);
            BindControl(cbbFather, PM_Project.Father, "SelectedValue", NullValue.NotSet);
            BindControl(ctbStarted, PM_Project.StartingDate);
            BindControl(ctbEnded, PM_Project.EndingDate);
            BindControl(rtbNote, PM_Project.Note, "Rtf");

            BindColumn(colBugsNumber, PM_Project.Code);
            BindColumn(colBugsDescription, PM_Project.Description);
            BindColumn(colBugsStatus, PM_Project.Status);

            BindObject(bdoProjectType, PM_Project.Type);
            BindCounter(cntNumber);
            BindControl(dgwBugs);
            base.OnBindData();
        }

        protected override bool OnAfterAddNew()
        {
            cbbStatus.SelectedValue = Status.ToDo.Long();
            bdoProjectType.Value = projectType.Int();
            ctbDate.Today = GlobalInfo.CurrentDate;
            return base.OnAfterAddNew();
        }

        protected override void OnDisableControlsForEdit()
        {
            cntNumber.Enabled = false;
            base.OnDisableControlsForEdit();
        }

        private void cbbFather_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (DocumentMode == DBMode.Browse)
                return;

            int project = 0;
            if (GlobalInfo.LoginInfo.ProviderType == ProviderType.SQLite)
                project = (int)ProjectManager.GetValue<long>();
            else
                project = ProjectManager.GetValue<int>();

            if (drProject.Find(project))
            {
                cbbProduct.SelectedValue = drProject.GetValue<string>(PM_Project.Product);
                cbbVersion.SelectedValue = drProject.GetValue<string>(PM_Project.Version);
            }
        }

        private void StepImprov_Load(object sender, EventArgs e)
        {

        }

        private void cbbFatherType_SelectedIndexChanged(object sender, EventArgs e)
        {
            rrProjects = new RRProjects(CounterManager.GetValue());
            if (GlobalInfo.LoginInfo.ProviderType == ProviderType.SQLite)
                cbbFather.AttachDataReader<long>(rrProjects, PM_Project.Code, PM_Project.Description);
            else
                cbbFather.AttachDataReader<int>(rrProjects, PM_Project.Code, PM_Project.Description);
        }

        private class PartialCounter : EnumsManager<Counters>
        {
            public Counters CounterType { get; set; }
            public PartialCounter(System.Resources.ResourceManager resource)
                : base(resource)
            {}

            public override bool DisplayValue(Counters t)
            {
                if (CounterType == Counters.Improvement)
                    return t == Counters.Project;
                else
                    return  t == Counters.Project ||
                            t == Counters.Improvement;
            }
        }
    }

    #region DbManager dbmanagerStepImprov

    /// <summary>
    /// Classe derivata per gestioni particolari
    /// </summary>
    internal class dbmanagerStepImprov : DBManager
    {
        public dbmanagerStepImprov(string name, RadarForm radar, DocumentForm document)
            : base(name, radar, document)
        { }

        protected override void dAdapter_MasterRowUpdating(object sender, SqlABRowUpdatingEventArgs e)
        {
            base.dAdapter_MasterRowUpdating(sender, e);
        }

        protected override string CreateMasterQuery()
        {
            this.Table = new PM_Project();
            QueryBuilder qB = new QueryBuilder();
            qB.AddSelect();
            qB.AddFrom(this.Table);
            qB.AddCompare(PM_Project.Type, "@p1");
            qB.AddCompare(PM_Project.Code, "@p2");

            return qB.Query;
        }

        protected override string CreateSlaveQuery(string name)
        {
            //QueryBuilder qb = new QueryBuilder();
            if (name == "SLAVESTATUS")
            {
                QueryBuilder qb1 = new QueryBuilder();
                QueryBuilder qb = new QueryBuilder();

                qb1.AddSelect();
                qb1.AddFrom(PM_Project.Name);
                qb1.AddCompare(PM_Project.FatherType, "@p3");
                qb1.AddCompare(PM_Project.Father, "@p4");

                qb.AddManualQuery(@"select Y.* from {0} X inner join {1} Y
                                    on X.{2} = Y.{3} and X.{4} = Y.{5}",
                                        PM_Project.Name,
                                        PM_Project.Name,
                                        PM_Project.Type.Name,
                                        PM_Project.FatherType.Name,
                                        PM_Project.Code.Name,
                                        PM_Project.Father.Name);
                qb.AddCompare(string.Format("X.{0}", PM_Project.FatherType.Name), "@p3", "=");
                qb.AddCompare(string.Format("X.{0}", PM_Project.Father.Name), "@p4", "=");

                return string.Concat(qb1.Query, " UNION ", qb.Query);
            }
            else
                return "";
        }

        protected override List<SqlABParameter> CreateMasterParam()
        {
            List<SqlABParameter> PList = new List<SqlABParameter>();

            SqlABParameter sParam1 = new SqlABParameter("@p1", PM_Project.Type);
            sParam1.Value = PM_Project.Type.DefaultValue;
            PList.Add(sParam1);

            SqlABParameter sParam2 = new SqlABParameter("@p2", PM_Project.Code);
            sParam2.Value = PM_Project.Code.DefaultValue;
            PList.Add(sParam2);
            return PList;
        }

        protected override List<SqlABParameter> CreateSlaveParam(string name)
        {
            List<SqlABParameter> PList = new List<SqlABParameter>();
            if (name == "SLAVESTATUS")
            {
                SqlABParameter p3 = new SqlABParameter("@p3", PM_Project.FatherType);
                p3.Value = 99999;
                PList.Add(p3);
                SqlABParameter p4 = new SqlABParameter("@p4", PM_Project.Father);
                p4.Value = 0;
                PList.Add(p4);
                SqlABParameter p5 = new SqlABParameter("@p5", PM_Project.Type);
                p5.Value = Counters.Bug.Int();
                PList.Add(p5);
            }

            return PList;
        }

        protected override void SetParameters(ApplicationLibrary.ExtendedControls.IRadarParameters key, DBCollection collection)
        {
            collection.Parameter[0].Value = key[0];
            collection.Parameter[1].Value = key[1];
        }
    }

    #endregion DbManager dbmanagerStepImprov

    public class Steps : StepImprov
    {
        public Steps()
            : base("StepForm", Counters.Step)
        { }
    }

    public class Improvements : StepImprov
    {
        public Improvements()
            : base("ImprovementForm", Counters.Improvement)
        { }
    }
}